package com.paw.ruoyi.admin.core.aop;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import com.paw.ruoyi.admin.common.annotion.SkipLogParam;
import com.paw.ruoyi.admin.common.annotion.SkipResponseLog;
import com.paw.ruoyi.admin.core.util.RemoteRequestUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public abstract class AbstractWebLogAspect {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  /**
   * 切点 ：实现类需声明切点的包名
   */
  protected abstract void webLog ();

  /**
   * 前置处理，记录请求信息
   *
   * @param joinPoint joinPoint
   * @throws Throwable Throwable
   */
  @Before("webLog()")
  protected void doBefore (JoinPoint joinPoint) throws Throwable {
    try {
      MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

      ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
      HttpServletRequest request = attributes.getRequest();

      StringBuilder builder = new StringBuilder();
      builder.append("\n     class name : ").append(methodSignature.getDeclaringTypeName());
      builder.append("\n   class method : ").append(methodSignature.getName());

      SkipLogParam skipLogParam = methodSignature.getMethod().getAnnotation(SkipLogParam.class);
      if (null == skipLogParam) {
        builder.append("\n     class args : ").append(JSON.toJSONString(joinPoint.getArgs()));
      }

      builder.append("\n     request ip : ").append(RemoteRequestUtils.getRemoteIP(request));
      builder.append("\n    request url : ").append(request.getRequestURL());
      builder.append("\n request method : ").append(request.getMethod());
      builder.append("\n");
      logger.info(builder.toString());

    } catch (Exception e) {
      logger.error("error : " + e.getMessage());
    }
  }

  /**
   * 后置处理，记录结果信息
   *
   * @param ret Object
   * @throws Throwable Throwable
   */
  @AfterReturning(returning = "ret", pointcut = "webLog()")
  protected void doAfterReturning (JoinPoint joinPoint, Object ret) throws Throwable {
    try {
      if (null == ret) {
        logger.info("json response : ret is null !");
        return;
      }
      if (ret.toString().startsWith("<xml>")) {
        logger.info("xml response : \n" + ret);
      } else {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        SkipResponseLog skipResponseLog = methodSignature.getMethod().getAnnotation(SkipResponseLog.class);
        if (null == skipResponseLog) {
          logger.info("json response : \n" + JSON.toJSONString(ret));
        }
      }
    } catch (Exception e) {
      logger.error("error response : " + ret);
    }
  }
}
